/*
 * Explosion.java
 * Purpose:   Creates explosions using a simple particle system.
 * Author:    pattersa
 * Date:      ???
 * Rev:       [2008-02-15, Ryan J. Bovorasmy] Added comments (for adv. graphics report).
 */
package protovitae.engine;

import java.awt.Color;
import javax.media.opengl.GL;
import protovitae.data.Position;

/**
 * Creates explosions using a simple particle system.
 * @author pattersa
 */
public class Explosion {
    private Position centerOfBlast; // The position of the center of the blast.
    private Color explosionColor; // The color of the explosion.

    private float time;
    private int numPoints = 500;
    private float[][] pointList = new float[numPoints][3];
    private float[] pointTime = new float[numPoints];
    private float[][] pointVelocity = new float[numPoints][2];
    private float[][] pointDirection = new float[numPoints][2];
    private int[] colorList = new int[numPoints];
    private final float MEAN_VELOCITY = 3.0f;
    private final float TIME_DELTA = 0.25f;  
    private final int EDGE = 1;

    /**
     * Initializes the blast points.
     * @param c The color of the blast.
     * @param p The senter position of the blast.
     */
    public Explosion(Color c, Position p) {
        this.centerOfBlast = p;
        this.explosionColor = c;
        makePointList();
    }

    /**
     * Creats a list of points.
     */
    private void makePointList() {
        float angleP, velocity, direction;
        int i;

        for (i = 0; i < numPoints; i++) {
            pointList[i][0] = (float)centerOfBlast.getX(); 
            pointList[i][1] = (float)centerOfBlast.getY(); 
            pointList[i][2] = (float)centerOfBlast.getZ(); 
            pointTime[i] = 0.0f;
            colorList[i] = 1;   //alive
            angleP = (float) (Math.random() * 10 + 60 * Math.PI / 180.0);
            direction = (float) (Math.random() * 360 * Math.PI / 180);
            pointDirection[i][0] = (float) Math.cos(direction);
            pointDirection[i][1] = (float) Math.sin(direction);
            velocity = MEAN_VELOCITY + (float) (Math.random() * 5 - 2);
            pointVelocity[i][0] = velocity * (float) Math.cos(angleP);
            pointVelocity[i][1] = velocity * (float) Math.sin(angleP);
        }
        time = 0.0f;
    }

    /**
     * Updates the position of the points.
     */
    private void updatePointList() {
        float distance;

        for (int i = 0; i < numPoints; i++) {
            distance = pointVelocity[i][0] * time;

            /* X and Y */
            pointList[i][0] = pointDirection[i][0] * distance;
            pointList[i][1] = pointDirection[i][1] * distance;
            pointList[i][2] = pointDirection[i][1] * distance;

            pointList[i][0] += centerOfBlast.getX();
            pointList[i][1] -= centerOfBlast.getY();
            pointList[i][2] -= centerOfBlast.getZ();
            
            if (distance > EDGE) {
                colorList[i] = 0;  //Dead 
            }

            pointTime[i] += TIME_DELTA;
        }
        time += TIME_DELTA;
    }

    /**
     * Draw the points.
     * @param gl
     */
    public void render(GL gl) {
        updatePointList();
        
        
        gl.glDisable(GL.GL_LIGHTING);
        

        gl.glBegin(GL.GL_POINTS);
        for (int i = 0; i < numPoints; i++) {
            /* Draw alive particles. */
            if (colorList[i] != 0) {
                double red = (double) explosionColor.getRed() / 255.0f;
                double green = (double) explosionColor.getGreen() / 255.0f;
                double blue = (double) explosionColor.getBlue() / 255.0f;
                double alpha = 1.0;

                gl.glColor4d(red,green, blue, alpha);

                gl.glVertex3fv(pointList[i], 0);
            }
        }
        gl.glEnd();
        
        gl.glEnable(GL.GL_LIGHTING);
    }

    /**
     * Keep this explosion going?
     * @return true if this explosion should continue going, otherwise false.
     */
    public boolean continueBlowingUp() {
        boolean alive = false;
        for (int i = 0; i < numPoints; i++) {
            /* Draw alive particles. */
            if (colorList[i] != 0) {
                alive = true;
            }
        }
        
        if(time>15){
            alive = false;
        }
        return alive;
    }
}
